
package com.swak.frame.exception;

import com.swak.frame.enums.BasicErrCode;
import com.swak.frame.enums.IResultCode;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * Assert.java  断言
 * @author colley.ma
 * @date 2022/9/20 14:25
 */
public abstract class Assert {

	public static void isTrue(boolean expression,String message) {
		if (!expression) {
			throw new ArgumentException(message);
		}
	}


	public static void state(boolean expression, String message) {
		if (!expression) {
			throw new ArgumentException(message);
		}
	}

	public static void state(boolean expression) {
		state(expression, "[ApiAssert failed] - this state invariant must be true");
	}

	public static void isTrue(boolean expression, Supplier<String> message) {
		if (!expression) {
			throw new ArgumentException(BasicErrCode.INVALID_PARAMETER, message.get());
		}
	}

	public static void isTrue(boolean expression, IResultCode errorCode, String message) {
		if (!expression) {
			throw new ArgumentException(errorCode, message);
		}
	}

	public static void isTrue(boolean expression) {
		isTrue(expression, "[Assertion failed] - this expression must be true");
	}

	public static void notNull(Object object, IResultCode errorCode, String message) {
		if (object == null) {
			throw new ArgumentException(errorCode, message);
		}
	}

	public static void notNull(Object object, IResultCode errorCode) {
		if (object == null) {
			throw new ArgumentException(errorCode);
		}
	}

	public static void notNull(Object object, String message) {
		notNull(object, BasicErrCode.INVALID_PARAMETER, message);
	}

	public static void notNull(Object object, Supplier<String> msgSupplier) {
		notNull(object, BasicErrCode.INVALID_PARAMETER, msgSupplier.get());
	}

	public static void notNull(Object object) {
		notNull(object, BasicErrCode.INVALID_PARAMETER, "[Assertion failed] - the argument " + object + " must not be null");
	}

	public static void notHasNull(String message, Object... objects) {
		boolean hasNull = Stream.of(objects).anyMatch(Objects::isNull);
		if (hasNull) {
			throw new ArgumentException(BasicErrCode.INVALID_PARAMETER, message);
		}
	}

	public static void notEmpty(Collection<?> collection) {
		notEmpty(collection,
				"[Assertion failed] - this collection must not be empty: it must contain at least 1 element");
	}

	public static void notEmpty(Collection<?> collection, String message) {
		if (CollectionUtils.isEmpty(collection)) {
			throw new ArgumentException(message);
		}
	}

	public static void notEmpty(Collection<?> collection, IResultCode errorCode) {
		if (CollectionUtils.isEmpty(collection)) {
			throw new ArgumentException(errorCode);
		}
	}

	public static void notBlank(CharSequence css, String message) {
		if (StringUtils.isBlank(css)) {
			throw new ArgumentException(message);
		}
	}

	public static void notBlank(CharSequence css, IResultCode errorCode) {
		if (StringUtils.isBlank(css)) {
			throw new ArgumentException(errorCode);
		}
	}

	public static void notEmpty(Map<?, ?> map, String message) {
		if (MapUtils.isEmpty(map)) {
			throw new ArgumentException(message);
		}
	}

	public static void notEmpty(Map<?, ?> map, IResultCode errorCode) {
		if (MapUtils.isEmpty(map)) {
			throw new ArgumentException(errorCode);
		}
	}

	public static void notEmpty(Map<?, ?> map) {
		notEmpty(map, "[Assertion failed] - this map must not be empty; it must contain at least one entry");
	}

	public static void state(boolean expression, IResultCode errorCode) {
		if (!expression) {
			throw new ArgumentException(errorCode);
		}
	}
}
